/*     */ package com.zimbra.cs.index.query;
/*     */ 
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.index.DBQueryOperation;
/*     */ import com.zimbra.cs.index.QueryOperation;
/*     */ import com.zimbra.cs.mailbox.Mailbox;
/*     */ import java.text.DateFormat;
/*     */ import java.text.ParseException;
/*     */ import java.util.Calendar;
/*     */ import java.util.Date;
/*     */ import java.util.GregorianCalendar;
/*     */ import java.util.Locale;
/*     */ import java.util.TimeZone;
/*     */ import java.util.regex.Matcher;
/*     */ import java.util.regex.Pattern;
/*     */ import org.apache.lucene.document.DateTools;
/*     */ import org.apache.lucene.document.DateTools.Resolution;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public final class DateQuery
/*     */   extends Query
/*     */ {
/*     */   public static enum Type
/*     */   {
/* 109 */     APPT_START,  APPT_END,  CONV_START,  CONV_END,  BEFORE,  AFTER,  DATE,  MDATE,  DAY,  WEEK,  MONTH,  YEAR;
/*     */     
/*     */     private Type() {} }
/* 112 */   private static final Pattern NUMERIC_DATE_PATTERN = Pattern.compile("^[0-9]+$");
/* 113 */   private static final Pattern RELATIVE_DATE_PATTERN = Pattern.compile("^([+-])([0-9]+)([mhdwy]|mi|minute[s]?|hour[s]?|day[s]?|week[s]?|month[s]?|year[s]?)?$");
/*     */   
/*     */   private long lowestTime;
/*     */   private boolean lowerEq;
/*     */   private long highestTime;
/*     */   private boolean higherEq;
/*     */   private final Type type;
/*     */   
/*     */   public DateQuery(Type type)
/*     */   {
/* 123 */     this.type = type;
/*     */   }
/*     */   
/*     */   public long getLowestTime() {
/* 127 */     return this.lowestTime;
/*     */   }
/*     */   
/*     */   public boolean isLowestInclusive() {
/* 131 */     return this.lowerEq;
/*     */   }
/*     */   
/*     */   public long getHighestTime() {
/* 135 */     return this.highestTime;
/*     */   }
/*     */   
/*     */   public boolean isHighestInclusive() {
/* 139 */     return this.higherEq;
/*     */   }
/*     */   
/*     */   public boolean hasTextOperation()
/*     */   {
/* 144 */     return false;
/*     */   }
/*     */   
/*     */   public QueryOperation compile(Mailbox mbox, boolean bool)
/*     */   {
/* 149 */     DBQueryOperation op = new DBQueryOperation();
/* 150 */     switch (this.type) {
/*     */     case APPT_START: 
/* 152 */       op.addCalStartDateRange(this.lowestTime, this.lowerEq, this.highestTime, this.higherEq, evalBool(bool));
/* 153 */       break;
/*     */     case APPT_END: 
/* 155 */       op.addCalEndDateRange(this.lowestTime, this.lowerEq, this.highestTime, this.higherEq, evalBool(bool));
/* 156 */       break;
/*     */     case MDATE: 
/* 158 */       op.addMDateRange(this.lowestTime, this.lowerEq, this.highestTime, this.higherEq, evalBool(bool));
/* 159 */       break;
/*     */     default: 
/* 161 */       op.addDateRange(this.lowestTime, this.lowerEq, this.highestTime, this.higherEq, evalBool(bool));
/*     */     }
/*     */     
/*     */     
/* 165 */     return op;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public void parseDate(String src, TimeZone tz, Locale locale)
/*     */     throws ParseException
/*     */   {
/* 175 */     Date beginDate = null;
/* 176 */     Date endDate = null;
/* 177 */     this.lowestTime = -1L;
/* 178 */     this.highestTime = -1L;
/* 179 */     boolean hasExplicitComparasins = false;
/* 180 */     boolean explicitLT = false;
/* 181 */     boolean explicitGT = false;
/* 182 */     boolean explicitEq = false;
/*     */     
/* 184 */     if (src.isEmpty()) {
/* 185 */       throw new ParseException(src, 0);
/*     */     }
/*     */     
/*     */ 
/* 189 */     if (src.charAt(src.length() - 1) == ',') {
/* 190 */       src = src.substring(0, src.length() - 1);
/* 191 */       if (src.isEmpty()) {
/* 192 */         throw new ParseException(src, 0);
/*     */       }
/*     */     }
/*     */     
/* 196 */     char ch = src.charAt(0);
/* 197 */     if ((ch == '<') || (ch == '>')) {
/* 198 */       switch (this.type) {
/*     */       case BEFORE: 
/*     */       case AFTER: 
/* 201 */         throw new ParseException(src, 0);
/*     */       }
/*     */       
/* 204 */       hasExplicitComparasins = true;
/*     */       
/* 206 */       if (src.length() <= 1) {
/* 207 */         throw new ParseException(src, 0);
/*     */       }
/*     */       
/* 210 */       char ch2 = src.charAt(1);
/* 211 */       if ((ch2 == '=') && (src.length() <= 2)) {
/* 212 */         throw new ParseException(src, 0);
/*     */       }
/*     */       
/* 215 */       if (ch == '<') {
/* 216 */         explicitLT = true;
/* 217 */       } else if (ch == '>') {
/* 218 */         explicitGT = true;
/*     */       }
/* 220 */       if (ch2 == '=') {
/* 221 */         src = src.substring(2);
/* 222 */         explicitEq = true;
/*     */       } else {
/* 224 */         src = src.substring(1);
/*     */       }
/*     */       
/* 227 */       if (src.isEmpty()) {
/* 228 */         throw new ParseException(src, 0);
/*     */       }
/*     */     }
/*     */     
/*     */ 
/* 233 */     if (src.equalsIgnoreCase("today")) {
/* 234 */       src = "-0d";
/*     */     }
/* 236 */     if (src.equalsIgnoreCase("yesterday")) {
/* 237 */       src = "-1d";
/*     */     }
/*     */     
/* 240 */     int field = 0;
/* 241 */     switch (this.type) {
/*     */     case APPT_START: 
/*     */     case APPT_END: 
/*     */     case MDATE: 
/*     */     case BEFORE: 
/*     */     case AFTER: 
/*     */     case DATE: 
/*     */     case DAY: 
/* 249 */       field = 5;
/* 250 */       break;
/*     */     case WEEK: 
/* 252 */       field = 3;
/* 253 */       break;
/*     */     case MONTH: 
/* 255 */       field = 2;
/* 256 */       break;
/*     */     case YEAR: 
/* 258 */       field = 1;
/*     */     }
/*     */     
/*     */     
/*     */ 
/*     */ 
/* 264 */     String mod = null;
/* 265 */     Matcher matcher = NUMERIC_DATE_PATTERN.matcher(src);
/* 266 */     if (matcher.lookingAt()) {
/* 267 */       long dateLong = Long.parseLong(src);
/* 268 */       beginDate = new Date(dateLong);
/* 269 */       endDate = new Date(dateLong + 1000L);
/*     */     }
/*     */     else {
/* 272 */       matcher = RELATIVE_DATE_PATTERN.matcher(src);
/* 273 */       if (matcher.lookingAt())
/*     */       {
/*     */ 
/*     */ 
/*     */ 
/* 278 */         mod = src.substring(matcher.start(1), matcher.end(1));
/* 279 */         String reltime = src.substring(matcher.start(2), matcher.end(2));
/*     */         
/* 281 */         if (matcher.start(3) != -1)
/*     */         {
/*     */ 
/* 284 */           String what = src.substring(matcher.start(3), matcher.end(3));
/*     */           
/* 286 */           switch (what.charAt(0)) {
/*     */           case 'm': 
/* 288 */             field = 2;
/* 289 */             if ((what.length() > 1) && (what.charAt(1) == 'i')) {
/* 290 */               field = 12;
/*     */             }
/*     */             break;
/*     */           case 'h': 
/* 294 */             field = 11;
/* 295 */             break;
/*     */           case 'd': 
/* 297 */             field = 5;
/* 298 */             break;
/*     */           case 'w': 
/* 300 */             field = 3;
/* 301 */             break;
/*     */           case 'y': 
/* 303 */             field = 1;
/*     */           }
/*     */           
/*     */         }
/*     */         
/*     */ 
/* 309 */         GregorianCalendar cal = new GregorianCalendar();
/* 310 */         if (tz != null) {
/* 311 */           cal.setTimeZone(tz);
/*     */         }
/*     */         
/* 314 */         cal.setTime(new Date());
/*     */         
/*     */ 
/*     */ 
/* 318 */         switch (field) {
/*     */         case 1: 
/* 320 */           cal.set(2, 0);
/*     */         
/*     */         case 2: 
/* 323 */           cal.set(5, 1);
/* 324 */           cal.set(11, 0);
/* 325 */           cal.set(12, 0);
/* 326 */           cal.set(13, 0);
/* 327 */           break;
/*     */         case 3: 
/* 329 */           cal.set(7, cal.getFirstDayOfWeek());
/*     */         
/*     */         case 5: 
/* 332 */           cal.set(11, 0);
/*     */         
/*     */         case 10: 
/*     */         case 11: 
/* 336 */           cal.set(12, 0);
/*     */         
/*     */         case 12: 
/* 339 */           cal.set(13, 0);
/*     */         }
/*     */         
/* 342 */         int num = Integer.parseInt(reltime);
/* 343 */         if (mod.equals("-")) {
/* 344 */           num *= -1;
/*     */         }
/*     */         
/* 347 */         cal.add(field, num);
/* 348 */         beginDate = cal.getTime();
/*     */         
/* 350 */         cal.add(field, 1);
/* 351 */         endDate = cal.getTime();
/*     */       } else {
/*     */         try {
/* 354 */           beginDate = parse(src, tz, locale);
/*     */         } catch (ParseException e) {
/* 356 */           if ((locale == null) || (!Locale.ENGLISH.getLanguage().equals(locale.getLanguage()))) {
/* 357 */             beginDate = parse(src, tz, Locale.ENGLISH);
/*     */           } else {
/* 359 */             throw e;
/*     */           }
/*     */         }
/*     */         
/* 363 */         Calendar cal = Calendar.getInstance();
/* 364 */         if (tz != null) {
/* 365 */           cal.setTimeZone(tz);
/*     */         }
/* 367 */         cal.setTime(beginDate);
/* 368 */         cal.add(field, 1);
/* 369 */         endDate = cal.getTime();
/*     */       }
/*     */     }
/*     */     
/* 373 */     ZimbraLog.search.debug("Parsed date range to: (%s - %s)", new Object[] { beginDate, endDate });
/*     */     
/*     */ 
/* 376 */     if (!hasExplicitComparasins) {
/* 377 */       switch (this.type) {
/*     */       case BEFORE: 
/* 379 */         explicitLT = true;
/* 380 */         explicitEq = false;
/* 381 */         break;
/*     */       case AFTER: 
/* 383 */         explicitGT = true;
/* 384 */         explicitEq = false;
/* 385 */         break;
/*     */       case APPT_START: 
/*     */       case APPT_END: 
/*     */       case DATE: 
/*     */       case MONTH: 
/*     */       case YEAR: 
/* 391 */         explicitEq = true;
/*     */       }
/*     */       
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 411 */     if (explicitLT) {
/* 412 */       if (explicitEq) {
/* 413 */         this.lowestTime = -1L;
/* 414 */         this.lowerEq = false;
/* 415 */         this.highestTime = endDate.getTime();
/* 416 */         this.higherEq = false;
/*     */       } else {
/* 418 */         this.lowestTime = -1L;
/* 419 */         this.lowerEq = false;
/* 420 */         this.highestTime = beginDate.getTime();
/* 421 */         this.higherEq = false;
/*     */       }
/* 423 */     } else if (explicitGT) {
/* 424 */       if (explicitEq) {
/* 425 */         this.lowestTime = beginDate.getTime();
/* 426 */         this.lowerEq = true;
/* 427 */         this.highestTime = -1L;
/* 428 */         this.higherEq = false;
/*     */       } else {
/* 430 */         this.lowestTime = endDate.getTime();
/* 431 */         this.lowerEq = true;
/* 432 */         this.highestTime = -1L;
/* 433 */         this.higherEq = false;
/*     */       }
/*     */     } else {
/* 436 */       this.lowestTime = beginDate.getTime();
/* 437 */       this.lowerEq = true;
/* 438 */       this.highestTime = endDate.getTime();
/* 439 */       this.higherEq = false;
/*     */     }
/*     */   }
/*     */   
/*     */   private Date parse(String src, TimeZone tz, Locale locale)
/*     */     throws ParseException
/*     */   {
/* 446 */     DateFormat df = locale != null ? DateFormat.getDateInstance(3, locale) : DateFormat.getDateInstance(3);
/*     */     
/* 448 */     df.setLenient(false);
/* 449 */     if (tz != null) {
/* 450 */       df.setTimeZone(tz);
/*     */     }
/* 452 */     return df.parse(src);
/*     */   }
/*     */   
/*     */   public void dump(StringBuilder out)
/*     */   {
/* 457 */     out.append("DATE:");
/* 458 */     out.append(this.type);
/* 459 */     out.append(',');
/* 460 */     out.append(DateTools.timeToString(this.lowestTime, DateTools.Resolution.MINUTE));
/* 461 */     out.append('-');
/* 462 */     out.append(DateTools.timeToString(this.highestTime, DateTools.Resolution.MINUTE));
/*     */   }
/*     */   
/*     */   public void sanitizedDump(StringBuilder out)
/*     */   {
/* 467 */     out.append("DATE:");
/* 468 */     out.append(this.type);
/* 469 */     out.append(',');
/* 470 */     out.append("$DATE");
/* 471 */     out.append('-');
/* 472 */     out.append("$DATE");
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/index/query/DateQuery.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */